package com.foreveross.taskservice.mq.mbean;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.management.MBeanServerConnection;
import javax.management.MBeanServerInvocationHandler;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;

import org.apache.activemq.broker.jmx.BrokerViewMBean;
import org.apache.activemq.broker.jmx.QueueViewMBean;
import org.apache.commons.lang3.StringUtils;

import com.foreveross.taskservice.infra.cfg.PropertyUtils;
import com.foreveross.taskservice.infra.cfg.activemq.MQStatePropertiesLoader;

/**
 * 简易的MQ队列代理工厂
 * 不再依赖spring，基本可以达到动态的目的了
 * 目前仅支持队列，不支持主题，可以扩展
 * @author Administrator
 *
 */
public class MQViewMBeanProxyFactory {
	
	private static MQViewMBeanProxyFactory instance;
	private Map<String,org.apache.activemq.broker.jmx.QueueViewMBean> cache;
	private BrokerViewMBean brokerViewMBean;
	private String brokerObjectName;
	private MBeanServerConnection mbsc;
	private MQViewMBeanProxyFactory(){
		cache=new HashMap<String,org.apache.activemq.broker.jmx.QueueViewMBean>();
	};
	public static MQViewMBeanProxyFactory getInstance(){
		if(instance==null){
			instance=new MQViewMBeanProxyFactory();
		}
		return instance;
	}
	/**
	 * 返回一个brokerMBean
	 * @return
	 */
	public BrokerViewMBean getBorkerViewMBean(){
		if(this.brokerViewMBean==null){
			try {
				ObjectName objectName=new ObjectName(getBrokerObjectName());
				brokerViewMBean=MBeanServerInvocationHandler.newProxyInstance(mbsc, objectName, BrokerViewMBean.class, true);
			} catch (Exception e) {
				e.printStackTrace();
			} 
		}
		return brokerViewMBean;
	}
	
	/**
	 * 返回指定队列的QueueMBean
	 * 如果队列不存在则返回null;
	 * @param queueName
	 * @return
	 */
	public synchronized org.apache.activemq.broker.jmx.QueueViewMBean getQueueViewMBean(String queueName){
		if(StringUtils.isBlank(queueName)){
			return null;
		}
		String name=getBrokerObjectName()+",destinationType=Queue,destinationName="+queueName;
		if(!cache.containsKey(name)){
			try {
				ObjectName mbeanName = new ObjectName(name);
				if(!getMBeanServerConnection().queryMBeans(mbeanName,null).isEmpty()){
					cache.put(name,(QueueViewMBean) MBeanServerInvocationHandler
							.newProxyInstance(getMBeanServerConnection(), mbeanName, QueueViewMBean.class, true));
				}
			} catch (Exception e) {
				e.printStackTrace();
			} 
		}
		return cache.get(name);
	}
	
	private String getBrokerObjectName(){
		if(this.brokerObjectName==null){
			this.brokerObjectName="org.apache.activemq:brokerName="+
					PropertyUtils.getProperty(MQStatePropertiesLoader.MQ_JMX_BROKER_NAME,MQStatePropertiesLoader.FILE_NAME,"localhost")
					+",type=Broker";
		}
		return this.brokerObjectName;
	}
	
	
	private MBeanServerConnection getMBeanServerConnection(){
		if(this.mbsc==null){
			try {
				JMXServiceURL url=new JMXServiceURL(PropertyUtils.getProperty(MQStatePropertiesLoader.MQ_JMX_SERVICEURL, MQStatePropertiesLoader.FILE_NAME));
				JMXConnector jmxc=JMXConnectorFactory.connect(url, null); 
				this.mbsc=jmxc.getMBeanServerConnection();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return this.mbsc;
	}
}
